package com.sdy.dcsb.web.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.sdy.common.model.Response;
import com.sdy.dcsb.biz.model.EsbInboundMain;
import com.sdy.dcsb.biz.model.EsbServiceTree;
import com.sdy.dcsb.biz.model.EsbServiceTreeCount;
import com.sdy.dcsb.biz.service.EsbInboundMainService;
import com.sdy.dcsb.biz.service.EsbServiceTreeService;
import com.sdy.dcsb.biz.service.UserOperationLogService;
import com.sdy.mvc.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import static org.springframework.util.StringUtils.isEmpty;

/**
 * <p>
 * 服务目录树表 前端控制器
 * </p>
 *
 * @author fb
 * @since 2019-09-24
 */
@Slf4j
@Controller
@RequestMapping("/EsbServiceTree")
@Api(tags = "服务目录树相关接口")
public class EsbServiceTreeController extends BaseController {
    @Autowired
    private EsbServiceTreeService esbServiceTreeService;
    @Autowired
    private EsbInboundMainService esbInboundMainService;
    @Autowired
    private UserOperationLogService userOperationLogService;

    /**
     * 查询子目录
     * @param id 主键,当前节点id
     * @param haschildren ,有无子节点 1:有,0:无
     * @param unrequiredId ,不需要展示的节点id
     * @return
     */
    @GetMapping("/listSubId")
    @ResponseBody
    @ApiOperation("查询子目录，最高父节点为0")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "Integer", name = "id", value = "当前节点id"),
            @ApiImplicitParam(dataType = "Integer", name = "haschildren", value = "有无子节点 1:有,0:无"),
            @ApiImplicitParam(dataType = "Integer", name = "unrequiredId", value = "不需要展示的节点id"),
    })
    public Response listSubId(Integer id, Integer haschildren, Integer unrequiredId) {
        if(isEmpty(id)) {
            return Response.error("请求的id不能为空");
        }
        QueryWrapper<EsbServiceTree> wrapper = new QueryWrapper<>();
        if(!isEmpty(haschildren)) {
            wrapper.eq("haschildren",haschildren);
        }
        if(!isEmpty(unrequiredId)) {
            wrapper.ne("id",unrequiredId);
        }
        wrapper.eq("par_id",id);
        wrapper.orderByDesc("code");
        wrapper.orderByAsc("id");
        List<EsbServiceTree> result = esbServiceTreeService.list(wrapper);
        List<EsbServiceTreeCount> resultCount = new ArrayList();
        for(int i=0; i< result.size(); i++) {
            EsbServiceTreeCount esbServiceTreeCount = new EsbServiceTreeCount();
            esbServiceTreeCount.setId(result.get(i).getId());
            esbServiceTreeCount.setCode(result.get(i).getCode());
            esbServiceTreeCount.setHaschildren(result.get(i).getHaschildren());
            esbServiceTreeCount.setLvl(result.get(i).getLvl());
            esbServiceTreeCount.setName(result.get(i).getName());
            esbServiceTreeCount.setStatus(result.get(i).getStatus());
            esbServiceTreeCount.setParId(result.get(i).getParId());
            esbServiceTreeCount.setCount(serviceCount(result.get(i).getId(), 0));
            resultCount.add(i, esbServiceTreeCount);
        }
        return Response.success(resultCount);
    }

    /**
     * 查询数据
     * @param id ,当前节点id
     * @return
     */
    @GetMapping("/select")
    @ResponseBody
    @ApiOperation("查询当前节点目录数据")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "Integer", name = "id", value = "当前节点id"),
    })
    public Response select(Integer id) {
        if(isEmpty(id)) {
            return Response.error("请求的id不能为空");
        }else {
            return Response.success(esbServiceTreeService.getById(id));
        }
    }

    /**
     * 删除数据
     * @param id ,当前节点id
     * @param haschildren ,当前节点有无子节点 1:有,0:无
     * @return
     */
    @GetMapping("/delete")
    @ResponseBody
    @ApiOperation("删除当前节点目录数据")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "Integer", name = "id", value = "当前节点id"),
            @ApiImplicitParam(dataType = "Integer", name = "haschildren", value = "当前节点有无子节点 1:有,0:无"),
    })
    public Response delete(HttpServletRequest request, Integer id, Integer haschildren) {
        if(isEmpty(id)) {
            return Response.error("请求的id不能为空");
        }
        if (haschildren == 1) {
            QueryWrapper<EsbServiceTree> wrapper = new QueryWrapper<>();
            wrapper.eq("par_id",id);
            List<EsbServiceTree> result = esbServiceTreeService.list(wrapper);
            if(result.size() >= 1 || id == 1) {
                return Response.error("当前目录下有数据不能被删除！");
            }else {
                userOperationLogService.savaUserLog(request, "删除服务树目录：" +
                        esbServiceTreeService.getById(id).getName());
                if(esbServiceTreeService.removeById(id)) {
                    return Response.success("删除目录成功");
                }else {
                    return Response.error("删除目录失败！");
                }
            }
        }else {
            return Response.error("当前目录不能被删除");
        }
    }

    /**
     * 修改目录名称
     * @param id ,当前节点id
     * @param name ,目录名称
     * @param haschildren ,当前节点有无子节点 1:有,0:无
     * @return
     */
    @GetMapping("/updateName")
    @ResponseBody
    @ApiOperation("修改当前节点目录名称")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "Integer", name = "id", value = "当前节点id"),
            @ApiImplicitParam(dataType = "String", name = "name", value = "目录名称"),
            @ApiImplicitParam(dataType = "Integer", name = "haschildren", value = "当前节点有无子节点 1:有,0:无"),
    })
    public Response updateName(HttpServletRequest request, Integer id, String name, Integer haschildren) {
        if(isEmpty(id)) {
            return Response.error("请求的id不能为空");
        }
        if (haschildren == 1) {
            EsbServiceTree esbServiceTree = new EsbServiceTree();
            if(!isEmpty(name)) {
                try {
                    name = URLDecoder.decode(name,"utf-8");
                }catch(IOException e) {

                }
                esbServiceTree.setName(name);
                userOperationLogService.savaUserLog(request, "修改服务树目录：" +
                        esbServiceTreeService.getById(id).getName() + "--->" + name);
                return Response.success(esbServiceTreeService.update(esbServiceTree, new UpdateWrapper<EsbServiceTree>().eq("id", id)));
            }else {
                return Response.error("目录名称不能为空");
            }
        }else {
            return Response.error("当前目录名称不能被修改");
        }
    }

    /**
     * 新增子目录
     * @param id ,当前节点id
     * @param lvl ,当前节点层级
     * @param haschildren ,当前节点有无子节点 1:有,0:无
     * @param name ,目录名称
     * @return
     */
    @GetMapping("/insertSubId")
    @ResponseBody
    @ApiOperation("新增当前目录的子目录")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "Integer", name = "id", value = "当前节点id"),
            @ApiImplicitParam(dataType = "Integer", name = "lvl", value = "当前节点层级"),
            @ApiImplicitParam(dataType = "Integer", name = "haschildren", value = "当前节点有无子节点 1:有,0:无"),
            @ApiImplicitParam(dataType = "String", name = "name", value = "目录名称"),
    })
    public Response insertSubId(HttpServletRequest request, Integer id, Integer lvl, Integer haschildren, String name) {
        if(isEmpty(id) || isEmpty(lvl)) {
            return Response.error("请求节点id或层级不能为空");
        }
        if (haschildren == 1) {
            EsbServiceTree esbServiceTree = new EsbServiceTree();
            if(!isEmpty(name)) {
                try {
                    name = URLDecoder.decode(name,"utf-8");
                }catch(IOException e) {

                }
                esbServiceTree.setCode(0);
                esbServiceTree.setHaschildren(1);
                esbServiceTree.setLvl(lvl+1);
                esbServiceTree.setName(name);
                esbServiceTree.setStatus("1");
                esbServiceTree.setParId(id);
                userOperationLogService.savaUserLog(request, "新增服务树目录：" + name);
                return Response.success(esbServiceTreeService.save(esbServiceTree));
            }else {
                return Response.error("目录名称不能为空");
            }
        }else {
            return Response.error("当前目录已是最底层，无法新增目录");
        }
    }

    /**
     * 节点迁移
     * @param id ,当前节点id
     * @param targetId ,目标节点id
     * @param targetLvl ,目标节点层级
     * @return
     */
    @GetMapping("/migrate")
    @ResponseBody
    @ApiOperation("节点迁移")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "Integer", name = "id", value = "当前节点id"),
            @ApiImplicitParam(dataType = "Integer", name = "targetId", value = "目标节点id"),
            @ApiImplicitParam(dataType = "Integer", name = "targetLvl", value = "目标节点层级"),
    })
    public Response migrate(HttpServletRequest request, Integer id, Integer targetId, Integer targetLvl) {
        if(isEmpty(id) || isEmpty(targetId) || isEmpty(targetLvl)) {
            return Response.error("请求的节点id或目标节点id或层级不能为空");
        }
        if(id.equals(targetId)) {
            return Response.error("不能迁移到自己目录下，请重新选择!");
        }
        EsbServiceTree esbServiceTree = new EsbServiceTree();
        esbServiceTree.setLvl(targetLvl+1);
        esbServiceTree.setParId(targetId);
        userOperationLogService.savaUserLog(request, "迁移服务树目录：" + esbServiceTreeService.getById(id).getName() +
                "--->" + esbServiceTreeService.getById(targetId).getName());
        esbServiceTreeService.update(esbServiceTree, new UpdateWrapper<EsbServiceTree>().eq("id", id));
        return Response.success("迁移成功");
    }


    /**
     * 节点目录下新增系统或从原子服务新增
     * @param id ,当前节点id
     * @param lvl ,节点层级
     * @param haschildren ,当前节点有无子节点 1:有,0:无
     * @param servname ,服务名称
     * @param servcode ,服务编码
     * @param servversion ,服务版本
     * @param status ,工作状态。1:工作态,0:注销态
     * @param atomcode ,原子服务编码
     * @param overTime ,超时时间/ms
     * @return
     */
    @GetMapping("/insert")
    @ResponseBody
    @ApiOperation("节点目录下新增系统或从原子服务新增")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "Integer", name = "id", value = "当前节点id"),
            @ApiImplicitParam(dataType = "Integer", name = "lvl", value = "节点层级"),
            @ApiImplicitParam(dataType = "Integer", name = "haschildren", value = "当前节点有无子节点 1:有,0:无"),
            @ApiImplicitParam(dataType = "String", name = "servname", value = "服务名称"),
            @ApiImplicitParam(dataType = "String", name = "servcode", value = "服务编码"),
            @ApiImplicitParam(dataType = "String", name = "servversion", value = "服务版本"),
            @ApiImplicitParam(dataType = "String", name = "status", value = "工作状态。1:工作态,0:注销态"),
            @ApiImplicitParam(dataType = "String", name = "atomcode", value = "原子服务编码"),
            @ApiImplicitParam(dataType = "String", name = "overTime", value = "超时时间/ms"),
    })
    public Response insert(HttpServletRequest request, Integer id, Integer lvl, Integer haschildren, String servname, String servcode,
                           String servversion, String status, String atomcode, String overTime) {
        if(isEmpty(id) && isEmpty(lvl) && isEmpty(haschildren)) {
            id = 1;
            lvl = 1;
            haschildren = 1;
        }
        if (haschildren == 1) {
            if(isEmpty(servname) || isEmpty(servcode) || isEmpty(servversion) || isEmpty(status) || isEmpty(overTime)) {
                return Response.error("服务参数不能为空");
            }else if(isEmpty(id) || isEmpty(haschildren)) {
                return Response.error("节点目录参数不能为空");
            }
            try {
                servname = URLDecoder.decode(servname,"utf-8");
                servcode = URLDecoder.decode(servcode,"utf-8");
                servversion = URLDecoder.decode(servversion,"utf-8");
                status = URLDecoder.decode(status,"utf-8");
                if(!isEmpty(atomcode)) {
                    atomcode = URLDecoder.decode(atomcode,"utf-8");
                }
                overTime = URLDecoder.decode(overTime,"utf-8");
            }catch  (IOException e) {

            }
            QueryWrapper<EsbInboundMain> wrapper = new QueryWrapper<>();
            wrapper.eq("servcode",servcode);
            List<EsbInboundMain> result = esbInboundMainService.list(wrapper);
            if(result.size() >= 1) {
                return Response.error("服务编码已存在，请重新输入");
            }
            EsbInboundMain esbInboundMain = new EsbInboundMain();
            esbInboundMain.setServname(servname);
            esbInboundMain.setServcode(servcode);
            esbInboundMain.setServversion(servversion);
            esbInboundMain.setStatus(status);
            esbInboundMain.setAtomcode(atomcode == null ? "" : atomcode);
            esbInboundMain.setOverTime(overTime);
            esbInboundMain.setCreateTime(new Date());
            esbInboundMain.setUpdateTime(new Date());
            userOperationLogService.savaUserLog(request, "新增服务信息：" + servcode);
            if(esbInboundMainService.save(esbInboundMain)){
                EsbServiceTree esbServiceTree = new EsbServiceTree();
                esbServiceTree.setCode(esbInboundMain.getServiceid());
                esbServiceTree.setHaschildren(0);
                esbServiceTree.setLvl(lvl+1);
                esbServiceTree.setName(servname);
                esbServiceTree.setStatus("1");
                esbServiceTree.setParId(id);
                userOperationLogService.savaUserLog(request, "新增服务树目录：" + servname);
                if(esbServiceTreeService.save(esbServiceTree)) {
                    return Response.success("新增服务和目录成功");
                }
                esbInboundMainService.removeById(esbInboundMain.getServiceid());
                return Response.error("新建目录失败");
            }
            return Response.error("新建服务失败");
        }
        return Response.error("此目录下不能新建目录");
    }

    /**
     * 查询当前目录下服务数量
     * @param id 当前节点id
     * @param count 初始值0
     * @return
     */
    private Integer serviceCount(Integer id, Integer count) {
        QueryWrapper<EsbServiceTree> wrapperSystem = new QueryWrapper<>();
        wrapperSystem.eq("par_id",id);
        wrapperSystem.ne("code",0);
        List<EsbServiceTree> resultSystem = esbServiceTreeService.list(wrapperSystem);
        count = count + resultSystem.size();
        QueryWrapper<EsbServiceTree> wrapper = new QueryWrapper<>();
        wrapper.eq("par_id",id);
        wrapper.eq("code",0);
        List<EsbServiceTree> result = esbServiceTreeService.list(wrapper);
        for(int i=0; i<result.size(); i++) {
            count = serviceCount(result.get(i).getId(), count);
        }
        return count;
    }

}
